import numpy as np
from math import sqrt

np_zeros = np.zeros
np_zeros_like = np.zeros_like

class Risk:
    #
    def __init__(self, model, loss_func): 
        self.model = model
        self.loss_func = loss_func
    #
    def evaluate(self, X, Y):
        YY = self.model.evaluate_all(X)
        L = self.loss_func.evaluate(YY, Y)
        return np.mean(L)
    #
    def gradient(self, X, Y):
        model_evaluate = self.model.evaluate
        YY = self.model.evaluate_all(X)
        V = self.loss_func.derivative(YY, Y) / len(X)
        grad = np.zeros(self.model.n_param, 'd')
        gradient = self.model.gradient
        for vk, Xk in zip(V, X):
            grad += vk * gradient(Xk)
        return grad
        
        
